#ifndef __CASH_H__
#define __CASH_H__

const static int CASH_STRATEGY_NORMAL = 1;
const static int CASH_STRATEGY_RETURN = 2;
const static int CASH_STRATEGY_REBATE = 3;

class CashSuper
{
public:
    virtual double AcceptCash(double money) = 0;
};

class CashNormal: public CashSuper
{
public:
    double AcceptCash(double money) override
    {
        return money;
    }
};

class CashReturn: public CashSuper
{
    double cond = 0;
    double ret = 0;
public:
    CashReturn(double cond, double ret): cond(cond), ret(ret) {}
    double AcceptCash(double money) override
    {
        double result = money;
        if (money >= cond) {
            result -= int(money / cond) * ret;
        }
        return result;
    }
};

class CashRebate: public CashSuper
{
    double rebate = 1.0;
public:
    CashRebate(double rebate): rebate(rebate) {}
    double AcceptCash(double money) override
    {
        return money * rebate;
    }
};

class CashContext
{
    CashSuper *cs = nullptr;
public:
    CashContext(int strategy)
    {
        switch (strategy)
        {
            case CASH_STRATEGY_NORMAL:
                cs = new CashNormal();
                break;
            case CASH_STRATEGY_RETURN:
                cs = new CashReturn(300, 100);
                break;
            case CASH_STRATEGY_REBATE:
                cs = new CashRebate(0.8);
                break;
            default:
                break;
        }
    }
    double GetResult(double money)
    {
        if (cs == nullptr) {
            return -1;
        }
        return cs->AcceptCash(money);
    }
};

#endif